package com.example.log.alarm.util;

import ch.qos.logback.classic.spi.IThrowableProxy;
import ch.qos.logback.classic.spi.StackTraceElementProxy;
import com.example.log.alarm.advice.thread.pool.ThreadInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.output.StringBuilderWriter;

import java.io.PrintWriter;
import java.io.Writer;
import java.lang.reflect.Field;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.concurrent.ThreadFactory;

/**
 * @program: spring-agent
 * @description:
 * @author: zt22328 赵儒定
 * @create: 2023-05-05 14:20
 **/
@Slf4j
public class WrapperUtil {

    public static String getStackTrace(Throwable throwable) {
        Writer writer = new StringBuilderWriter();
        throwable.printStackTrace(new PrintWriter(writer));
        return writer.toString();
    }

    public static String md5Key(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] digest = md.digest(input.getBytes());
            StringBuilder sb = new StringBuilder();
            for (byte b : digest) {
                sb.append(String.format("%02x", b & 0xff));
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            return null;
        }
    }

    public static String getStackTrace(IThrowableProxy iThrowableProxy) {
        String className = iThrowableProxy.getClassName();
        String message = iThrowableProxy.getMessage();
        StringBuilder msg = new StringBuilder(className);
        msg.append(": ").append(message);
        for (StackTraceElementProxy traceElement : iThrowableProxy.getStackTraceElementProxyArray()) {
            msg.append("\n\t").append(traceElement.getSTEAsString());
        }

        for (IThrowableProxy suppressed : iThrowableProxy.getSuppressed()) {
            msg.append("\nSuppressed: ").append(getStackTrace(suppressed));
        }

        IThrowableProxy cause = iThrowableProxy.getCause();
        if (cause != null) {
            msg.append("\nCaused by: ").append(getStackTrace(cause));
        }

        return msg.toString();
    }

    public static LocalDateTime timeStamp2LocalDateTime(long timestamp) {
        return Instant.ofEpochMilli(timestamp).atZone(ZoneOffset.ofHours(8)).toLocalDateTime();
    }

    public static ThreadInfo getThreadInfo(ThreadFactory threadFactory) {
        Thread thread = threadFactory.newThread(() -> {});
        return new ThreadInfo(getThreadPoolName(thread.getName()), thread.isDaemon(), thread.getPriority());
    }

    public static String getThreadPoolName(String threadName) {
        return threadName.substring(0, threadName.lastIndexOf("-"));
    }
}
